/*!
 * jQuery gzoom 0.1
 * 2009 Giovanni Battista Lenoci <gianiaz@gianiaz.net>
 *
 * Based on minizoomPan plugin of Gian Carlo Mingati Version: 1.0 (18-JUNE-2009) http://www.gcmingati.net/wordpress/wp-content/lab/jquery/minizoompan/
 * Inspiration from jquery lightbox plugin http://leandrovieira.com/projects/jquery/lightbox/
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Requires:
 * jQuery v1.3.2 or later
 * jQuery ui.core.js v.1.7.1
 * jQuery ui.slider.js v.1.7.1
 *
 */
jQuery.fn.gzoom = function(settings) {
	settings = jQuery.extend({
  	sW: 10, // small image width
  	sH: 10, // small image height
  	lW: 20, // large image width
  	lH: 20, // large image height
    whiteSpace: 0,
    sliderWhiteSpace: 70,
    zoomInWhiteSpace: 27,
    buttonZoomInSrc: 'images/only_bt_zoomout.gif',
    buttonZoomInWidth: 17,
    buttonZoomInHeight: 13,
    buttonZoomOutSrc: 'images/only_bt_zoomin.gif',
    buttonZoomOutWidth: 15,
    buttonZoomOutHeight: 13,
  	step : 5,
  	drag: false,
  	frameColor: "#cecece",
  	frameWidth: 1,
  	re : /thumbs\//,
  	replace : '',
  	debug : false,
  	overlayBgColor : '#000',
    overlayOpacity:0.8,
    containerBorderSize: 10,
    containerResizeSpeed : 400,
  	loaderContent: "loading...",  // plain text or an image tag eg.: "<img src='yoursite.com/spinner.gif' />"
  	lightbox: false,
  	zoomIcon : "", // icon url, if not empty shown on the right-top corner of the image
  	canReset: false,
  	resetBgImage: '',
  	zoomBgImage: '',
    resetId:'reset-zoom',
    smoothMove: true,
    zoom0: false,
    zoom100: false
	}, settings);

	return this.each(function(){

	  var swapped = false;
	  	var zoom_box_width = settings.sW + settings.whiteSpace;
		var $div = jQuery(this).css({width: zoom_box_width, height: settings.sH, overflow:'hidden'}).addClass("minizoompan");
		$div.wrap('<div class="box-img-large"></div>').css({ width:zoom_box_width });
		var ig = $div.children().css({position: "relative"});
  		ig.width(settings.sW);
  		ig.height(settings.sH);
		jQuery(window).bind("load", function() {
  		ig.width(settings.sW);
  		ig.height(settings.sH);
		});


		//jQuery("<span class='loader'>"+settings.loaderContent+"<\/span>").insertBefore(ig);
		if(settings.zoomIcon != '' && settings.lightbox) {
		  var $zoom = jQuery('<img class="zoomIcon" src="'+settings.zoomIcon+'" alt="view larger" />').insertBefore(ig);
		  $zoom.load(function() {
  		  $zoom.css({'left':(settings.sW - $zoom.width())+'px'}).show();
		  });
		  $zoom.click(function() {
		    drawIface();
		  });
		} else if(settings.lightbox) {
			$div.click(function() {
			  drawIface();
			});
			$div.css({'cursor':'pointer'});
		}
		var $plusHtml = ' <div class="image-zoom bx-zoom">';
        $plusHtml    += '<img class="btn-zoom-in pos3" alt="Zoom In" src="'+settings.buttonZoomInSrc+'" width="'+ settings.buttonZoomInWidth + '" height="'+ settings.buttonZoomInHeight + '" id="zoom_in"/>';
        $plusHtml    += '<div class="line">&nbsp;</div>';
        $plusHtml    += '<a id="zoom-0"> </a>';
        $plusHtml    += '<div class="gzoomSlider"></div>';
        $plusHtml    += '<a id="zoom-100"> </a>';
        if(settings.canReset != false) $plusHtml    += '<a id="'+settings.resetId+'"> </a>';
        $plusHtml    += '<img class="btn-zoom-out pos1" alt="Zoom Out" src="'+settings.buttonZoomOutSrc+'" width="'+ settings.buttonZoomOutWidth + '" height="'+ settings.buttonZoomOutHeight + '" id="zoom_out"/>';
        $plusHtml    += '</div>';
		var $plus = jQuery($plusHtml).insertAfter($div);

        if(settings.canReset != false) {
			$("#"+settings.resetId).click(function(){
				$('.gzoomSlider').slider('value', 0);
				$(".bx-zoom").css('background-image','url('+settings.zoomBgImage+')');
			})
        }

        //		$div.append($plus);

		$('.gzoomSlider').css({ width:(settings.sW-settings.sliderWhiteSpace)+'px', border:'none'});
		$('#zoom_in').css("left",(settings.sW+settings.zoomInWhiteSpace)+"px");

		var mousehold;
        $('.btn-zoom-in').mousehold(function() {
                valore = parseInt($('.gzoomSlider').slider('value')) + settings.step;
                $('.gzoomSlider').slider('value', valore);
                return false;    
        });

		$('.btn-zoom-out').mousehold(function() {
		    valore = parseInt($('.gzoomSlider:visible').slider('value')) - settings.step;
		    $('.gzoomSlider:visible').slider('value', valore);
		});

        if(settings.zoom0) $("#zoom-0").click(function(){
            $('.gzoomSlider').slider('value',0);
        })

        if(settings.zoom100) $("#zoom-100").click(function(){
            $('.gzoomSlider').slider('value',100);
        })

		$('.gzoomSlider').slider({
            animate: settings.smoothMove,
            value:0,
		    min: 0,
		    max: 100,
		    step: settings.step,
            change: function(event, ui) {
                applyZoom(event, ui);
            },
            slide: function(event, ui) {
                applyZoom(event, ui);
            }
        });

		function applyZoom(event, ui)  {
          if(!swapped) {
                var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
                swapImage(ig, hiSrc);
                //$div.children("span.loader").fadeIn(250);//tungnt
                swapped = true;
            }
            val = ui.value;
            newWidth = settings.sW+((settings.lW-settings.sW)*val)/100;
            newHeight = settings.sH+((settings.lH-settings.sH)*val)/100;
            ig_pos = ig.position();
            
            if(settings.debug && typeof(console) != 'undefined') {
            console.log('new dimensions:'+newWidth+'x'+newHeight);
            }

            //Calculating newLeft by MinhBL
            imgWidth = ig.width();
            divWidth = $div.width();
            if(newWidth < divWidth) {
              newLeft = 0
            } else {
              newLeft = (divWidth - newWidth)/2;
            }
            if(newLeft > 0) newLeft = 0;
            if((divWidth - imgWidth) < 0 && newLeft < 0 && newLeft < (divWidth - newWidth)) newLeft = divWidth - newWidth;
            
            //Calculating newTop by MinhBL
            imgHeight = ig.height();
            divHeight = $div.height();
            if(newHeight < divHeight) {
              newTop = 0
            } else {
               newTop = (divHeight - newHeight)/2
            }
            if(newTop > 0) newTop = 0;
            if((divHeight - imgHeight) < 0 && newTop < 0 && newTop < (divHeight - newHeight)) newTop = divHeight - newHeight;

            ig.css({ width: newWidth, height: newHeight, left:newLeft, top:newTop});
            if(settings.canReset != false) {
                if(val > 0) {
                    $(".bx-zoom").css('background-image','url('+settings.resetBgImage+')');
                    $("#"+settings.resetId).css({'cursor':'pointer'});
                } else {
                    $(".bx-zoom").css('background-image','url('+settings.zoomBgImage+')');
                    $("#"+settings.resetId).css({'cursor':'default'});
                }
            }
        }
        
        function swapImage(param, uri){
			param.load(function () {
				//$div.children("span.loader").fadeOut(250);
			}).error(function (){
  			    show_popup("Error","Image does not exist or its SRC is not correct.");
			}).attr('src', uri);
		}

		var mouseX	= 0;						// X axis of current mouse position
		var mouseY	= 0;						// Y axis of current mouse position
		var igLeft	= parseInt(ig.css('left'));	// Left of the current zoomed image
		var igTop	= parseInt(ig.css('top'));	// Top of the current zoomed image
        
		function _mouseMove_over(divE, e) {
			var divWidth = divE.width();	// Width of the div element which contain the image zoom
			var divHeight = divE.height();	// Height of the div element which contain the image zoom
			var igW = ig.width();			// Width of the current zoomed image
			var igH = ig.height();			// Height of the current zoomed image
			var dOs = divE.offset();		// Top-Left of the div element which contain the image zoom

			var leftPan = (e.pageX - dOs.left) * (divWidth - igW) / (divWidth+settings.frameWidth*2);
			var topPan = (e.pageY - dOs.top) * (divHeight - igH) / (divHeight+settings.frameWidth*2);

			if(settings.debug && typeof(console) != 'undefined') {
			  console.log('left:'+leftPan+'|Top:'+topPan);
			}

			ig.css({left: leftPan, top: topPan});
		}

		function _mouseMove_drag(divE, mouseX, mouseY, igLeft, igTop, e) {
			var divWidth = divE.width();	// Width of the div element which contain the image zoom
			var divHeight = divE.height();	// Height of the div element which contain the image zoom
			var igW = ig.width();			// Width of the current zoomed image
			var igH = ig.height();			// Height of the current zoomed image

			var leftPan = igLeft + (e.pageX - mouseX);
			var topPan = igTop + (e.pageY - mouseY);

			if(settings.debug && typeof(console) != 'undefined') {
			  console.log('left:'+leftPan+'|Top:'+topPan);
			}
			leftPan = leftPan > 0 ? 0 : leftPan;
			leftPan = leftPan < 0 && leftPan < divWidth-igW ? divWidth-igW : leftPan;
			if(divWidth-igW > 0) leftPan = 0;
			topPan = topPan > 0 ? 0 : topPan;
			topPan = topPan < 0 && topPan < divHeight-igH ? divHeight-igH : topPan;
			if(divHeight-igH > 0) topPan = 0;

			ig.css({left: leftPan+'px', top: topPan+'px'});
			return true;
		}

		$div.bind("mousedown", function(e) {
			if(settings.drag==false) return false;
			mouseX	= e.pageX;					// X axis of current mouse position
			mouseY	= e.pageY;					// Y axis of current mouse position
			igLeft	= parseInt(ig.css('left'));	// Left of the current zoomed image
			igTop	= parseInt(ig.css('top'));	// Top of the current zoomed image

			$div.bind("mousemove", function(e){
				_mouseMove_drag($(this), mouseX, mouseY, igLeft, igTop, e);
			});
			document.onselectstart = function () { return false; };
			this.ondragstart = function() { return false; };
		});

		$div.bind("mousemove", function(e){
			if(settings.drag==true) return false;
			_mouseMove_over($(this),e);
		});

		$(document).bind("mouseup", function(e) {
			if(settings.drag==false) return false;
			mousedownwed = 0;
			$div.unbind("mousemove");
			document.onselectstart = null;
			$div.ondragstart = null;
		})

		if(typeof($.event.special.mousewheel) != 'undefined') {
			ig.mousewheel(function(event, delta) {
	      if (delta > 0) {
	        valore = parseInt($('.gzoomSlider').slider('value')) + settings.step;
	  		  $('.gzoomSlider').slider('value', valore);
	  		} else if (delta < 0) {
	  		  valore = parseInt($('.gzoomSlider').slider('value')) - settings.step;
		  	  $('.gzoomSlider').slider('value', valore);
		  	}
	      return false; // prevent default
	    });
	  }

		function resize_fx(intImageWidth,intImageHeight) {

      if(settings.debug && typeof(console) != 'undefined') {
        console.log('resize_fx('+intImageWidth+','+intImageHeight+')');
      }

			if(intImageWidth > ($(window).width()*80/100)) {
  			imgWidth = $(window).width()*80/100;
  			intImageHeight = (imgWidth/intImageWidth)*intImageHeight;
  			$('#zoomedimage').css({'width': imgWidth+'px', 'height':intImageHeight});
	      if(settings.debug && typeof(console) != 'undefined') {
	        console.log('Img dimensions 80% horizontal:'+imgWidth+'x'+intImageHeight);
	      }
			} else {
  			imgWidth = intImageWidth;
			}

			if(intImageHeight > $(window).height()*80/100) {
			  imgHeight = $(window).height()*80/100;
			  imgWidth = (imgHeight/intImageHeight)*imgWidth;
  			$('#zoomedimage').css({'width': imgWidth+'px', 'height':imgHeight});
	      if(settings.debug && typeof(console) != 'undefined') {
	        console.log('Img dimensions 80% vertical:'+imgWidth+'x'+imgHeight);
	      }
			} else {
			  imgHeight = intImageHeight;
			}

      if(settings.debug && typeof(console) != 'undefined') {
        console.log('Img dimensions:'+imgWidth+'x'+imgHeight);
      }

			// Get current width and height
			var intCurrentWidth = $('#imagebox').width();
			var intCurrentHeight = $('#imagebox').height();
			// Get the width and height of the selected image plus the padding
			var intWidth = (imgWidth + (settings.containerBorderSize * 2)); // Plus the imageÅ½s width and the left and right padding value
			var intHeight = (imgHeight + (settings.containerBorderSize * 2)); // Plus the imageÅ½s height and the left and right padding value



			// Diferences
			var intDiffW = intCurrentWidth - intWidth;
			var intDiffH = intCurrentHeight - intHeight;
			// Perfomance the effect
			$('#imagebox').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); });
			if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
				if ( $.browser.msie ) {
					___pause(250);
				} else {
					___pause(100);
				}
			}
			$('#lboximgdatacontainer').css({ width: imgWidth });
		};


		function drawIface() {

			$('body').append('<div id="gzoomoverlay"></div><div id="gzoomlbox"><div id="imagebox"><div id="gzoom-cont-img"><img id="zoomedimage"><div id="gzoomloading"><a href="#" id="gzoomloadinglink"><img src="images/loading.gif"></a></div></div></div><div id="gzoomlbox-con-imgdata"><div id="lboximgdatacontainer"><div id="gzoomlbox-image-details"><span id="gzoom-image-caption"></span></div></div></div></div>');

			$('#gzoomoverlay').css({
				backgroundColor:	settings.overlayBgColor,
				opacity:			settings.overlayOpacity,
				width:				$(window).width(),
				height:				$(document).height()
			}).fadeIn();

			// Calculate top and left offset for the gzoomlbox div object and show it
			$('#gzoomlbox').css({
				top:	$(window).scrollTop() + ($(window).height() / 10),
				left:	$(window).scrollLeft()
			}).show();

			$('#gzoomoverlay,#gzoomlbox').click(function() {
				close();
			});
			// If window was resized, calculate the new overlay dimensions
			$(window).resize(function() {
				$('#gzoomoverlay').css({
					width:		$(window).width(),
					height:		$(window).height()
				});
				// Calculate top and left offset for the jquery-lightbox div object and show it
				$('#gzoomlbox').css({
					top:	$(window).scrollTop() + ($(window).height() / 10),
					left:	$(window).scrollLeft()
				});
			});

			_set_image_to_view();
		}

		function _set_image_to_view() { // show the loading
			// Show the loading
			$('#gzoomlbox-con-imgdata').hide();
			$('#zoomedimage').hide();
			$('#gzoomloading').show();
			// Image preload process
			var objImagePreloader = new Image();
      if(!swapped) {
				var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
		  } else {
				var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
		  }
			objImagePreloader.onload = function() {
				$('#zoomedimage').attr('src',hiSrc);
				resize_fx(objImagePreloader.width,objImagePreloader.height);
			};
		  objImagePreloader.src = hiSrc;
		};

		function _show_image() {
 			$('#gzoomloading').hide();
			$('#zoomedimage').fadeIn(function() {
				_show_image_data();
			});
		};

		/**
		 * Show the image information
		 *
		 */
		function _show_image_data() {
			$('#lightbox-loading').hide();
      $('#gzoom-image-caption').html(ig.attr('title'));
			$('#gzoomlbox-con-imgdata').slideDown('fast');
		}

		function close() {
			$('#gzoomlbox').remove();
			$('#gzoomoverlay').fadeOut(function() { $('#gzoomoverlay').remove(); });
			$('embed, object, select').css({ 'visibility' : 'visible' });
		}

    function ___pause(ms) {
  		var date = new Date();
	  	curDate = null;
		  do { var curDate = new Date(); }
  		while ( curDate - date < ms);
	  };

	});

};

/**
 * jQuery mousehold plugin - fires an event while the mouse is clicked down.
 * Additionally, the function, when executed, is passed a single
 * argument representing the count of times the event has been fired during
 * this session of the mouse hold.
 *
 * @author Remy Sharp (leftlogic.com)
 * @date 2006-12-15
 * @example $("img").mousehold(200, function(i){  })
 * @desc Repeats firing the passed function while the mouse is clicked down
 *
 * @name mousehold
 * @type jQuery
 * @param Number timeout The frequency to repeat the event in milliseconds
 * @param Function fn A function to execute
 * @cat Plugin
 */

jQuery.fn.mousehold = function(timeout, f) {
    if (timeout && typeof timeout == 'function') {
        f = timeout;
        timeout = 100;
    }
    if (f && typeof f == 'function') {
        var timer = 0;
        var fireStep = 0;
        return this.each(function() {
            jQuery(this).mousedown(function() {
                fireStep = 1;
                var ctr = 0;
                var t = this;
                timer = setInterval(function() {
                    ctr++;
                    f.call(t, ctr);
                    fireStep = 2;
                }, timeout);
            })

            clearMousehold = function() {
                clearInterval(timer);
                if (fireStep == 1) f.call(this, 1);
                fireStep = 0;
            }
            
            jQuery(this).mouseout(clearMousehold);
            jQuery(this).mouseup(clearMousehold);
        })
    }
}